﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpGuiInterface.h"
#include "ElementId.h"
#include "Color.h"
#include "GcmpApiDeclaration.h"
namespace gcmp
{
    class IDocument;
    class IMaterialSelectionDialogListener;

    /// \brief 常用对话框创建类
    class GCMP_GUI_INTERFACE_EXPORT UiCommonDialog
    {
    public:
        /// \brief MessageBox按键类型
        enum class ButtonType : Int32
        {
            Invalid = 0,/// 无效按钮
            OK = 1 << 0,/// ok按钮
            Yes = 1 << 1,/// yes按钮
            Cancel = 1 << 2,/// cancel按钮
            No = 1 << 3,/// no按钮
            Ignore = 1 << 4,/// 忽略按钮
            IgnoreOnce = 1 << 5,/// 忽略一次按钮
            IgnoreAll = 1 << 6/// 忽略所有按钮
        };

        /// \brief MessageBox在主窗口的位置类型
        enum class PositionType : Int32
        {
            Invalid = 0,      /// 无效
            TopLeft = 1,      /// 当前UiView窗口的顶部左边
            TopRight = 2,     /// 当前UiView窗口的顶部右边
            BottomLeft = 3,   /// 当前UiView窗口的底部左边
            BottomRight = 4   /// 当前UiView窗口的底部右边
        };

        /// \brief 材质对话框主题
        enum class MaterialSelecitonDialogTheme : Int32
        {
            White = 0,  /// 白色主题
            Dark = 1    /// 黑色主题
        };

        /// \brief 打开一个MessageBox
        ///
        /// \param[in] windowTitle MessageBox的Title
        /// \param[in] message 显示在MessageBox上的message
        /// \param[in] buttonTypes 需要显示的MessageBox按键类型，如果有多个，使用‘|’运算符连接，比如(int)UiCommonDialog::ButtonType::Yes | (int)UiCommonDialog::ButtonType::No
        /// \return 点击按钮的类型
        static ButtonType ShowMessageBox(const std::wstring& windowTitle, const std::wstring& message, int buttonTypes);

        /// \brief 打开一个MessageBox
        ///
        /// \param[in] windowTitle MessageBox的Title
        /// \param[in] message 显示在MessageBox上的message
        /// \param[in] buttonTypes 需要显示的MessageBox按键类型，如果有多个，使用‘|’运算符连接，比如(int)UiCommonDialog::ButtonType::Yes | (int)UiCommonDialog::ButtonType::No
        /// \param[in] positionType MessageBox在主窗口的位置，默认放置在程序界面中间
        /// \param[in] width MessageBox的宽度，默认为350
        /// \param[in] high MessageBox的高度，默认为150 
        /// \return 点击按钮的类型
        static ButtonType ShowMiniMessageBox(const std::wstring& windowTitle, const std::wstring& message, int buttonTypes, int positionType = (int)UiCommonDialog::PositionType::BottomRight, int width = 350, int height = 150);

        
        /// \brief 打开一个带简单编辑框的输入对话框
        ///
        /// \param[in] windowTitle 输入对话框的Title
        /// \param[in] inputPrompt 用于提示编辑框应输入什么样信息的文本
        /// \param[in] defaultText 编辑框上默认显示的文本信息
        /// \param[out] inputText  输入对话框关闭时，编辑框上的文本信息
        /// \return 确定返回ButtonType::OK 
        ///         取消输入、直接关闭返回 ButtonType::Cancel
        static ButtonType ShowInputBox(const std::wstring& windowTitle, const std::wstring& inputPrompt, const std::wstring& defaultText, std::wstring& inputText);

        /// \brief 打开一个不含应用按钮的材质库对话框
        ///
        ///  点击确定，返回材质库对话框当前选中的材质Id，不会应用材质，对话框关闭
        ///
        /// \param[in] pDoc 文档指针，这个文档上的材质会出现在材质对话框上供用户选择
        /// \param[out] materialId 选中材质的id
        /// \param[in] token 云材质库得token。默认值为空，只能获得本地材质
        /// \param[in] libIdList 云材质库得库ID
        /// \param[in] productCode 产品代码，每个产品一个
        /// \param[in] theme 材质库对话框界面主题。目前支持黑白主题切换。默认为白色主题
        /// \param[in] currentMaterialId，材质Id。如果材质Id有效，则在项目材质库中默认选中该材质Id对应的材质实例
        /// \param[in] materialCategory，材质类别。如果材质Id无效且材质类别不为空，则在项目材质库中默认展开该材质类别
        /// \param[in] accountServiceBaseUrl，指向私有化的用户中心，使用本地缓存的材质，仍然需要私有化用户中心验证token
        /// \return 确定返回ButtonType::OK 
        ///         取消选择或者直接关闭返回 ButtonType::Cancel
        static ButtonType ShowMaterialSelectionDialog(IDocument *pDoc, ElementId& materialId, const std::wstring& token = L"", const std::wstring& libIdList = L"", const std::wstring& productCode = L"",
            const MaterialSelecitonDialogTheme theme = MaterialSelecitonDialogTheme::White, const ElementId& currentMaterialId = ElementId::InvalidID, const std::wstring& materialCategory = L"", const std::wstring& accountServiceBaseUrl = L"");
             
        
        /// \brief 打开一个含应用按钮的材质库对话框
        ///
        /// 点击应用，调用用户提供的材质库对话框事件响应函数，不关闭材质库对话框
        /// 点击确定，调用用户提供的材质库对话框事件响应函数，关闭材质库对话框
        ///
        /// \param[in] pDocument 文档指针，这个文档上的材质会出现在材质对话框上供用户选择
        /// \param[in] materialSelectionDialogListener 材质对话框事件
        /// \param[in] token 云材质库得token。默认值为空，只能获得本地材质
        /// \param[in] libIdList 云材质库得库ID
        /// \param[in] productCode 产品代码，每个产品一个
        /// \param[in] theme 材质库对话框界面主题。目前支持黑白主题切换。默认为白色主题
        /// \param[in] currentMaterialId，材质Id。如果材质Id有效，则在项目材质库中默认选中该材质Id对应的材质实例
        /// \param[in] materialCategory，材质类别。如果材质Id无效且材质类别不为空，则在项目材质库中默认展开该材质类别
        /// \param[in] accountServiceBaseUrl，指向私有化的用户中心，使用本地缓存的材质，仍然需要私有化用户中心验证token
        /// \return 确定返回ButtonType::OK 
        ///         取消选择或者直接关闭返回 ButtonType::Cancel
        /// \see IMaterialSelectionDialogListener
        static ButtonType ShowMaterialSelectionDialog(IDocument *pDocument, IMaterialSelectionDialogListener& materialSelectionDialogListener, const std::wstring& token = L"", const std::wstring& libIdList = L"", const std::wstring& productCode = L"",
            const MaterialSelecitonDialogTheme theme = MaterialSelecitonDialogTheme::White, const ElementId& currentMaterialId = ElementId::InvalidID, const std::wstring& materialCategory = L"", const std::wstring& accountServiceBaseUrl = L"");
        

        /// \brief 打开一个颜色对话框
        ///
        /// \param[in] init 初始颜色
        /// \param[out] seleted 选中的颜色
        /// \return 确定返回ButtonType::OK
        ///         取消选择或者直接关闭返回 ButtonType::Cancel
        static ButtonType ShowColorSelectionDialog(const Color& init, Color& seleted);


        /// \brief 打开一个用于选择文件或者文件夹的对话框
        ///
        /// \param[in] caption 对话框的Title
        /// \param[in] initialPath 默认打开的路径
        /// \param[in] filter 文件类型过滤规则，如GBMP_TR(L"DXF文件(*.dxf)")
        /// \param[in] bDirOnlyFlag 是否只能选择文件夹的标签，默认为false
        /// \return 所选择文件或文件夹的路径
        static std::wstring ShowOpenFileDialog(const std::wstring& caption, const std::wstring& initialPath, const std::wstring& filter, bool directoryOnlyFlag = false);
        
        /// \brief 打开一个用于选择文件或者文件夹的对话框
        ///
        /// 该方法主要适用于文件类型过滤规则中存在后缀名相同的场景，返回filterIndex用以区分是哪一个过滤项
        /// \param caption 对话框的Title
        /// \param initialPath 默认打开的路径
        /// \param filter 文件类型过滤规则，如L"DXF文件(*.dxf)"
        /// \param[out] filterIndex 获取选中的filter的索引号,从直观效果来看，从上向下的下标值从0依次递增；filterIndex为-1时，则用户点击了取消按钮。
        /// \param directoryOnlyFlag 是否只能选择文件夹的标签，默认为false
        /// \return 所选择文件或文件夹的路径
        static std::wstring ShowOpenFileDialog(const std::wstring& caption, const std::wstring& initialPath, const std::wstring& filter, int& filterIndex, bool directoryOnlyFlag = false);

        /// \brief 打开一个用于选择文件保存路径的对话框
        ///
        /// \param[in] caption 对话框的Title
        /// \param[in] initialPath 默认打开的路径
        /// \param[in] filter 文件类型过滤规则，如GBMP_TR(L"DXF文件(*.dxf)")
        /// \param[in] title 需要在对话框中选中的文件的文件名
        /// \return 文件保存路径
        static std::wstring ShowSaveFileDialog(const std::wstring& caption, const std::wstring& initialPath, const std::wstring& filter, const std::wstring& title = L"");


        /// \brief 打开一个专门用于关闭文档时提示用户是否保存的MessageBox
        ///
        /// \param[in] docName 要关闭的文档名
        /// \param[in] saveButtonStatus 保存按钮是否可点击
        /// \return 点击按钮的索引，0表示不保存，1表示保存，2表示取消，-1表示无效按钮
        static int ShowMessageBoxForCloseDocument(const std::wstring& docName, bool saveButtonStatus);

    };
}





